#include "StdMyString.h"
#include <cstring>
int count = 0;

StdMyString::StdMyString()
{
    capacity = 15;
    size = 0;
    s = new char[capacity];
    memset(s,0,capacity);
    /*std::cout<<"无参构造函数"<<std::endl;*/
}

StdMyString::StdMyString(const char *s)
{
    size = strlen(s);
    capacity = size >= 15 ? size + 1 : 15;
    this->s = new char[capacity];
    strcpy(this->s,s);
    /*std::cout<<"有参构造函数"<<std::endl;*/
}

StdMyString::StdMyString(const StdMyString& str)
{
    size = str.size;
    capacity = str.capacity;
    this->s = new char[capacity];
    strcpy(this->s, str.s);
    /*std::cout << "拷贝构造函数" << std::endl;*/
}

StdMyString::~StdMyString()
{
    // std::cout << "xigou函数" << std::endl;
    this->size = 0;
    this->capacity = 0;
    delete s;
}

//赋值运算符重载
StdMyString& StdMyString::operator=(const StdMyString &str)
{
    delete this->s;
    size = str.size;
    capacity = str.capacity;
    this->s = new char[capacity];
    strcpy(this->s,str.s);
    return *this;
}

StdMyString StdMyString::operator+(const StdMyString &str)
{
    StdMyString result;
    result.size = this->size + str.size;
    if(result.capacity <= result.size)
    {    
        delete result.s;
        result.capacity = result.size + 1;
        result.s = new char[result.capacity];
    }
    strcpy(result.s,this->s);
    strcat(result.s,str.s);

    return result;
}

StdMyString StdMyString::operator+(const char c)
{
    StdMyString result;
    result.size = this->size + 1;
    if(result.capacity <= result.size)
    {    
        delete result.s;
        result.capacity = result.size + 1;
        result.s = new char[result.capacity];
    }
    strcpy(result.s,this->s);
    *(result.s + size) = c;
    *(result.s + size + 1) = '\0';
    return result;
}


StdMyString &StdMyString::operator+=(const StdMyString &str)
{
    *this = *this + str;
    return *this;
}

StdMyString& StdMyString::operator+=(const char c)
{
    if (this->capacity <= this->size)
    {
        this->capacity *= 2;
        char* newStr = new char[this->capacity];
        strcpy(newStr, this->s);
        delete this->s; 
        this->s = newStr;
    }
    *(this->s + size) = c;
    this->size++;
    *(this->s + size + 1) = '\0';
    return *this;
}

StdMyString StdMyString::operator-(const StdMyString& str)
{
    StdMyString result(*this);
    char* dest = strstr(result.s, str.s);
    while (dest != NULL)
    {
        char* back = dest + str.size;
        while (*back != '\0')
            *dest++ = *back++;
        *dest = '\0';
        result.size -= str.size;
        dest = strstr(result.s, str.s);
    }
    
    return result;
}

StdMyString& StdMyString::operator-=(const StdMyString& str)
{
    *this = *this - str;
    return *this;
}

bool StdMyString::operator>(const StdMyString& str)
{
    return strcmp(this->s,str.s) > 0;
}

bool StdMyString::operator<(const StdMyString& str)
{
    return strcmp(this->s,str.s) > 0;
}

bool StdMyString::operator==(const StdMyString& str)
{
    return strcmp(this->s, str.s) == 0;
}

bool StdMyString::operator>=(const StdMyString& str)
{
    return strcmp(this->s, str.s) >= 0;
}

bool StdMyString::operator<=(const StdMyString& str)
{
    return strcmp(this->s, str.s) <= 0;
}

bool StdMyString::operator!=(const StdMyString& str)
{
    return strcmp(this->s, str.s) != 0;
}

bool StdMyString::operator&&(const StdMyString& str)
{
    return this->size != 0 && str.size != 0;
}

char& StdMyString::operator[](int index)
{
    return this->s[index];
}

// StringList StdMyString::Split(const char *demil)
// {
//     StringList list;
//     StdMyString *temp = new StdMyString;
//     temp->s = strtok(this->s,demil); 
//     while(temp->s != NULL)
//     {
//         list = list + temp->s;
//         temp->s = strtok(NULL,demil);
//     }
//     delete []temp;
//     return list;
// }

//StdMyString::operator int()
//{
//    return atoi(this->s);
//}
//
//StdMyString::operator double()
//{
//    return atof(this->s);
//}

std::ostream& operator<<(std::ostream &os, const StdMyString &s)
{
    os << s.s;
    return os;
}

std::istream& operator>>(std::istream& is, StdMyString& s)
{
    char c = 0;
    while ((c = getchar()) != '\n')
        s += c;
    return is;
}

StringList::StringList()
{
    // std::cout << "无参构造函数" << std::endl;
    size = 0;
    capacity = 5;
    stringList = new StdMyString[capacity];
}

StringList::StringList(const StdMyString* list)
{
    // std::cout << "带参构造函数" << std::endl;
    this->size = list->size;
    this->capacity = this->size > 5 ? size + 1 : 5;
    this->stringList = new StdMyString[capacity];
    for (int i = 0; i < this->size; i++)
    {
        this->stringList[i].capacity = list[i].capacity;
        this->stringList[i].size = list[i].size;
        strcpy(this->stringList[i].s, list[i].s);
    }
}

StringList::StringList(const StringList& list)
{
    // std::cout << "拷贝构造函数" << std::endl;
    this->capacity = list.capacity;
    this->size = list.size;
    this->stringList = new StdMyString[this->capacity];

    for (int i = 0; i < this->size; i++)
    {
        strcpy(this->stringList[i].s, list.stringList[i].s);
    }
}

StringList::~StringList()
{
    
    // std::cout << "析构函数" << std::endl;
    // for (int i = 0; i < capacity; i++)
    // {
    //     // stringList[i].~StdMyString();
    // } 
    this->capacity = 0;
    this->size = 0;
    delete []this->stringList;
}

void StringList::show()
{
    for (int i = 0; i < size; i++)
        std::cout << this->stringList[i].s << std::endl;
}

StringList StringList::operator=(const StringList &list)
{
    this->size = list.size;
    this->capacity = list.capacity;
    for(int i = 0; i < list.size; i++)
    {
        this->stringList[i] = list.stringList[i];
    }
    return *this;
}

StringList StringList::operator+(const StringList &list)
{
    StringList result;
    result.size = this->size + list.size;
    if(result.capacity <= result.size)
    {
        result.capacity *= 2;
        result.stringList = new StdMyString[result.capacity];
    }
    for(int i = 0; i < this->size; i++)
        result.stringList[i] = this->stringList[i];
    for(int i = 0; i < list.size; i++)
        result.stringList[this->size + i] = list.stringList[i];
    return result;
}

StringList StringList::operator+(const StdMyString &str)
{
    StringList result;
    result.size = this->size + 1;
    if (result.capacity <= result.size)
    {
        delete []result.stringList;
        result.capacity *= 2;
        result.stringList = new StdMyString[result.capacity];
    }
    for (int i = 0; i < this->size; i++)
    {
        strcpy(result.stringList[i].s, this->stringList[i].s);
        result.stringList[i].size = this->stringList[i].size;
    }
    result.stringList[result.size-1] = str;
    return result;
}

StringList StringList::operator-(const StdMyString &str)
{
    StringList result(*this);
    for(int i = 0; i < result.size; i++)
    {
        if((result.stringList[i] == str) == true)
        {
            for(int j = i; j < result.size - 1; j++)
            {
                result.stringList[j] = result.stringList[j+1];
            }
            result.size--;
            i--;
        }
    }
    return result;
}

StringList& StringList::operator+=(const StringList &list)
{
    *this = *this + list;
    return *this;
}

StringList& StringList::operator+=(const StdMyString &str)
{
    if(this->capacity <= this->size)
    {
        this->capacity *= 2;
        StdMyString *newStrList = new StdMyString[this->capacity];
        for(int i = 0; i < this->size; i++)
            newStrList[i] = this->stringList[i]; 
        delete []this->stringList;
        this->stringList = newStrList;
    }
    this->stringList[this->size] = str;
    this->size++;
    return *this;
}

StringList &StringList::operator-=(const StdMyString &str)
{
    *this = *this - str;
    return *this;
}

StdMyString &StringList::operator[](int index)
{
    return this->stringList[index];
}

StringList StringList::Split(StdMyString str, const char *demil)
{

    StringList list;
    StdMyString *temp = new StdMyString;
    temp->s = strtok(str.s,demil); 
    while(temp->s != NULL)
    {
        list = list + temp->s;
        temp->s = strtok(NULL,demil);
    }
    return list;
}